/*
 * =====================================================================================
 *
 *       Filename:  corners.cpp
 *
 *    Description:  Defines function returning the number of corners in a given binary
 *                  image
 *
 *        Version:  1.0
 *        Created:  03/07/12 16:12:49
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Moos Hueting (mh), mooshueting@gmail.com
 *   Organization:  UCL
 *
 * =====================================================================================
 */
#include <iostream>
#include <cv.h>
#include <highgui.h>

using namespace cv;

Mat hitandmiss(Mat src, Mat strel, Point origin) {
    Mat invSrc;
    bitwise_not(src, invSrc);

    Mat invStrel;
    bitwise_not(strel, invStrel);

    Mat temp1;
    Mat temp2;

    erode(src, temp1, strel, origin, 1, BORDER_REPLICATE);
    erode(invSrc, temp2, invStrel, origin, 1, BORDER_REPLICATE);

    Mat final;

    bitwise_and(temp1, temp2, final);

    return final;
}

int corners(Mat src) {
    // create structuring element
    Mat strel(2, 2, CV_8UC1, Scalar(255));
    strel.at<unsigned char>(1, 1) = 0;

    Mat final;

    Mat workingMat = hitandmiss(src, strel, Point(0,0));
    final = workingMat.clone();

    flip(strel, strel, 0);
    workingMat = hitandmiss(src, strel, Point(0, 1));

    bitwise_or(final, workingMat, final);

    flip(strel, strel, 1);
    workingMat = hitandmiss(src, strel, Point(1, 1));

    bitwise_or(final, workingMat, final);

    flip(strel, strel, 0); 
    workingMat = hitandmiss(src, strel, Point(1, 0));

    bitwise_or(final, workingMat, final);

    return countNonZero(final);

}

int main(int argc, char* argv[]) {
    
    // load image
    Mat im = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
    threshold(im, im, 100, 255, THRESH_BINARY);

    std::cout << corners(im) << std::endl;

}
